# -*- coding: utf-8 -*-
###############################################################################
# file    : utils.py
# author  : wangyubin
# date    : 2013-07-31
#
# brief   : common functions
# history : init
#           add session check at 2013-08-20
###############################################################################

import base64
import datetime
import os, commands, shutil
import time

import uliweb
from uliweb.utils import image

from comm_app.my_log import App_Log

DATE_FORMAT1 = '%Y-%m-%d_%H-%M-%S.%f'
DATE_FORMAT2 = '%Y/%m/%d %H-%M-%S.%f'
DATE_FORMAT3 = '%Y-%m-%d %H-%M-%S'
DATE_FORMAT4 = '%Y-%m-%d %H:%M:%S'
DATE_FORMAT5 = '%Y-%m-%d'
DATE_FORMAT6 = '%Y-%m-%d %H:%M:%S.%f'

#========================================
# tools
#========================================

def generate_uuid():
    import uuid
    return str(uuid.uuid1())

def generate_key(lst_str):
    """
    生成base64 string
    """
    return base64.b64encode('='.join(lst_str))

def count_resource(folder):
    """
    计算文件夹 folder 中的资源个数
    同名的 视频和图片 算一个资源
    """
    temp_dic = {}
    for f in os.listdir(folder):
        (n, e) = os.path.splitext(f)
        temp_dic[n] = 0

    return len(temp_dic)


def fix_str_len(s, length=15, rep="···"):
    """
    设置 s 长度为 length
    如果 s 的长度 > length : 用 rep 表示多余的内容
    如果 s 的长度 <=length : 直接返回 s

    注: 首先按 utf-8 解码，所以一个中文(全角)字符的长度是 1
    ex. rep变量中的 3个点是中文全角 len(rep) = 6, 而 len(rep.decode('utf-8')) = 3
    """
    if len(s) > length:
        s = s.decode('utf-8')[:length-len(rep.decode('utf-8'))].encode('utf-8') + rep

    return s


def md5_crypt(s):
    """ md5 加密
    """
    import md5
    return md5.md5(s).hexdigest()


def get_path_depths(fullpath, depths=1):
    """根据参数获取指定层数的文件夹
    ex.  /a/b/c/d/e/f/g.jpg
    get_path_depths(0) : g.jpg
    get_path_depths(1) : f/g.jpg
    get_path_depths(2) : e/f/g.jpg
    get_path_depths(3) : d/e/f/g.jpg
    """
    if depths == 0:
        return os.path.basename(fullpath)

    l = []
    l.append(os.path.basename(fullpath))
    for i in range(depths):
        fullpath = os.path.dirname(fullpath)
        l.append(os.path.basename(fullpath))
        
    l.reverse()
    return '/'.join(l)
        

def get_request(request):
    """ 获取 request
    """
    if request.method == "GET":
        return request.GET
    else:
        return request.POST

#========================================
# convert 
#========================================
def datetime2str(dt, fmt=DATE_FORMAT1):
    """
    按照指定格式将 datetime 转为 string
    """
    return dt.strftime(fmt)

def str2datetime(s, fmt=DATE_FORMAT1):
    """
    按照指定格式将 string 转为 datetime
    """
    return datetime.datetime.strptime(s, fmt)

def num2str(num, str_len=2):
    """
    将 num 转换为指定长度的 string
    如果转换后的 string 长度 < str_len, 在 string 前面补0
    """

    s = str(num)
    while len(s) < str_len:
        s = "0" + s

    return s


#========================================
# about file control
#========================================
def upload_file(filepath, file):
    if not os.path.exists(os.path.dirname(filepath)):
        os.makedirs(os.path.dirname(filepath))

    file.save(filepath)
    return os.path.getsize(filepath)


def upload_image_file(filepath, filestream, filesize=(300, 200)):
    if not os.path.exists(os.path.dirname(filepath)):
        os.makedirs(os.path.dirname(filepath))
    try:
        resized_stream = image.resize_image_string(filestream.read(), filesize)
    except:
        return 0
    with open(filepath, 'w') as f:
            f.write(resized_stream)
    if not image.test_image(filepath,True):
        return 0
    else:
        return os.path.getsize(filepath)


def download_file(environ, filepath):
    print filepath
    from uliweb.utils import filedown
    filename = os.path.basename(filepath)
    return filedown.filedown(environ, filename, real_filename=filepath, action='download')


def create_file(filepath, overwrite=True):
    if not os.path.exists(filepath):
        os.mknod(filepath)
        return

    if overwrite:
        os.remove(filepath)
        os.mknod(filepath)


def remove_file_or_dir(path):
    if os.path.exists(path):
        if os.path.isfile(path):
            os.remove(path)
        if os.path.isdir(path):
            # os.removedirs(path)
            shutil.rmtree(path)


def create_directory(dirpath, overwrite=False):
    if not os.path.exists(dirpath):
        os.makedirs(dirpath)
        return

    if overwrite:
        os.removedirs(dirpath)
        os.makedirs(dirpath)


def copy_file(from_file, to_file):

    if not os.path.exists(from_file): # 待拷贝的文件不存在
        return

    if from_file == to_file:    # 文件路径一样
        return 
        
    create_directory(os.path.dirname(to_file))
    shutil.copy(from_file, to_file)

#========================================
# about video file
#========================================
def segment_video(seg_src, info_cmd, seg_start_cmd):
    """视频切片，保存在原始视频同一路径下。
    切片后的视频文件夹的名称和原始视频一样（不要后缀名）

    非 .ts文件直接返回
    """

    seg_src_name = os.path.basename(seg_src)
    (filename, fileext) = os.path.splitext(seg_src_name)
    abs_seg_src = os.path.abspath(seg_src)

    if fileext != ".ts":
        # App_Log.logger.warn("Not .ts file")
        return False

    while True:
        if get_server_state(info_cmd):
            time.sleep(2)
            continue

        seg_dir = os.path.splitext(seg_src)[0]
        # App_Log.logger.debug("seg_dir: " + seg_dir)
        # print "seg_dir:", seg_dir
        if os.path.exists(seg_dir):
            shutil.rmtree(seg_dir)

        os.makedirs(seg_dir)
        #seg_tar = os.path.join(seg_dir, filename)
        cur_dir = os.path.abspath(os.curdir)
        os.chdir(seg_dir)   # 在新建的视频目录中视频切片
        cmd_seg = seg_start_cmd % (abs_seg_src, filename)
        cmd_seg += ' seg-%d.ts'
        App_Log.logger.debug(cmd_seg)
        start_cmd(cmd_seg)
        os.chdir(cur_dir)
        break

    return True


def video_thumbnail(video_src, video_thumb_cmd):
    """
    截取视频中的一段作为缩略图
    """
    thumbnail_param = os.path.splitext(video_src)[0]
    cmd = video_thumb_cmd % (video_src, thumbnail_param)
    if start_cmd(cmd):
        return thumbnail_param + '.png'


#========================================
# linux service control
#========================================
def start_server(cmd_check, *cmd_starts):
    # 启动脚本不会立即返回的场合，用os.system
    try:
        for start in cmd_starts:
            os.system(start)
        return get_server_state(cmd_check)
    except Exception, e:
        print e
        return False

def stop_server(cmd_check, *cmd_stops):
    try:
        for stop in cmd_stops:
            commands.getstatusoutput(stop)
        return not get_server_state(cmd_check)
    except Exception, e:
        print e
        return False


def get_server_state(cmd_check):
    # 存在组播service - Ture  / 不存在 - False
    (status, output) = commands.getstatusoutput(cmd_check)
    if status == 0:
        if output.find('\n') > 0: # 只有 commands.getstatusoutput 本身
            return True

    return False


def start_cmd(*cmd_starts):
    try:
        for start in cmd_starts:
            os.system(start)
        return True
    except Exception, e:
        print e
        return False


def excute_cmd(cmd):
    """ 执行命令并获取返回值
    """
    (status, output) = commands.getstatusoutput(cmd)
    App_Log.logger.debug("[excute_cmd - status]: " + str(status))
    App_Log.logger.debug("[excute_cmd - output]: " + output)
    if status == 0:
        return output
    else:
        return None
